﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Noris.Schedule.Support.Services;
using System.Drawing;
using System.Windows.Forms;
using Noris.Schedule.Planning.ProcessData;
using Noris.Schedule.Support;

namespace Noris.Schedule.Planning.Services
{
	#region FIXACE ELEMENTU
	/// <summary>
	/// Funkce pro fixaci elementu (operace)
	/// </summary>
	internal class ElementFixCls : IFunctionMenuItem
	{
		/// <summary>
		/// Tady funkce deklaruje, pro které případy chce být vidět v nabídce.
		/// A pokud ano, tak jak se jmenuje, kde v nabídce je a jaký má obrázek.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsFunctionSuitableFor(FunctionMenuItemSuitableArgs args)
		{
			// Element lze fixovat buď jako CapacityLink (pak jde o WorkUnit):
			bool isSuitable1 = (
				args.KeyGraphMode == RowGraphMode.TaskCapacityLink &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberWork);
			//   anebo v grafu Gant, pokud je element ze třídy Task:
			bool isSuitable2 = (
				args.KeyGraphMode == RowGraphMode.Gantt &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberTask);
			bool isSuitable = isSuitable1 || isSuitable2;
			if (isSuitable)
			{
				args.EnabledStateDependingOnElement = true;
				args.MenuCaption = "Fixovat operaci";
				args.MenuToolTipText = "Zafixuje tuto operaci v čase a místě.\r\nFixovaná operace se nebude přesouvat při doplánování.";
				args.MenuImage = PicLibrary22.Pin_red_FromFile;
				args.MenuGroup = "TASK";
				args.MenuOrder = -250;
			}
			return isSuitable;
		}
		/// <summary>
		/// Vizuální vrstva se ptá, zda tato položka menu je pro aktuální elementy enabled nebo disabled.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsMenuItemEnabledFor(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return false;

			List<DataPointerStr> elements = args.InputElements;      // Seznam všech vybraných elementů (clicked + selected)
			foreach (DataPointerStr pointer in elements)
			{
				// Pokud jakýkoli jeden task, který je majitelem elementu, je nefixovaný, vrátím true (lze jej fixovat):
				CapacityPlanWorkItemCls task = planningData.FindTaskC(pointer);
				if (task != null && !task.IsFixedTask)
					return true;
			}
			return false;
		}
		/// <summary>
		/// Vstupní metoda do výkonné části pluginu
		/// </summary>
		/// <param name="args"></param>
		void IFunctionMenuItem.Run(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return;

			PlanningInteractiveFixArgs fixArgs = new PlanningInteractiveFixArgs();
			fixArgs.InputItemsFillFrom(args, true, true);
			fixArgs.FixSetting = (InteractiveFixSetting)(InteractiveFixSetting.Fix | InteractiveFixSetting.SelectedTask);

			planningData.InteractiveSetFix(fixArgs);

			fixArgs.ResultCopyTo(args);
		}
	}
	#endregion
	#region ZRUŠENÍ FIXACE ELEMENTU
	/// <summary>
	/// Funkce pro zrušení fixace elementu (operace)
	/// </summary>
	internal class ElementUnFixCls : IFunctionMenuItem
	{
		/// <summary>
		/// Tady funkce deklaruje, pro které případy chce být vidět v nabídce.
		/// A pokud ano, tak jak se jmenuje, kde v nabídce je a jaký má obrázek.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsFunctionSuitableFor(FunctionMenuItemSuitableArgs args)
		{
			// Element lze fixovat buď jako CapacityLink (pak jde o WorkUnit):
			bool isSuitable1 = (
				args.KeyGraphMode == RowGraphMode.TaskCapacityLink &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberWork);
			//   anebo v grafu Gant, pokud je element ze třídy Task:
			bool isSuitable2 = (
				args.KeyGraphMode == RowGraphMode.Gantt &&
				args.KeyAreaType == FunctionMenuItemAreaType.GraphElement &&
				args.KeyElementClassNumber == Noris.Schedule.Planning.ProcessData.Constants.ClassNumberTask);
			bool isSuitable = isSuitable1 || isSuitable2;
			if (isSuitable)
			{
				args.EnabledStateDependingOnElement = true;
				args.MenuCaption = "Zrušit fixaci operace";
				args.MenuToolTipText = "Zruší fixování této operace v čase a místě.\r\nNefixovanou operaci systém při doplánování může přesunout.";
				args.MenuImage = PicLibrary22.Goup4_FromFile;
				args.MenuGroup = "TASK";
				args.MenuOrder = -249;
			}
			return isSuitable;
		}
		/// <summary>
		/// Vizuální vrstva se ptá, zda tato položka menu je pro aktuální elementy enabled nebo disabled.
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		bool IFunctionMenuItem.IsMenuItemEnabledFor(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return false;

			List<DataPointerStr> elements = args.InputElements;      // Seznam všech vybraných elementů (clicked + selected)
			foreach (DataPointerStr pointer in elements)
			{
				// Pokud jakýkoli jeden task, který je majitelem elementu, je fixovaný, vrátím true (lze jej odfixovat):
				CapacityPlanWorkItemCls task = planningData.FindTaskC(pointer);
				if (task != null && task.IsFixedTask)
					return true;
			}
			return false;
		}
		/// <summary>
		/// Vstupní metoda do výkonné části pluginu
		/// </summary>
		/// <param name="args"></param>
		void IFunctionMenuItem.Run(FunctionMenuItemRunArgs args)
		{
			PlanningDataCls planningData;
			if (!PlanningDataCls.TryGetPlanningData(args.DataSource, out planningData)) return;

			PlanningInteractiveFixArgs fixArgs = new PlanningInteractiveFixArgs();
			fixArgs.InputItemsFillFrom(args, true, true);
			fixArgs.FixSetting = (InteractiveFixSetting)(InteractiveFixSetting.Unfix | InteractiveFixSetting.SelectedTask);

			planningData.InteractiveSetFix(fixArgs);

			fixArgs.ResultCopyTo(args);
		}
	}
	#endregion
}
